package jinyilw.swing.visuals.border;

import jinyilw.swing.ComponentTools;
import jinyilw.swing.FontTools;
import jinyilw.swing.graphics.GraphicsTools;
import jinyilw.swing.graphics.RenderingConfig;
import jinyilw.swing.i18n.ICSetting;
import jinyilw.swing.rlaf.UITools;
import jinyilw.swing.rlaf.theme.RThemeColor;

import javax.swing.Icon;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.RoundRectangle2D;

public class RichTitleBorder extends AbstractITitleBorder
{
	private static final long serialVersionUID = 2533602715958016698L;
	private static final AlphaComposite alphaComposite = ComponentTools.alphaComposite;
	private static final Color hiColor = new Color(255, 255, 255, 220);
	private static final Color loColor = new Color(130, 130, 130);
	private Icon icon;
	private int shadowSize = 3;
	private int innerSpace = 4;
	private final int arc = 12;
	private final Color shadowColor = Color.black;
	private final int shadowOpacity = 96;
	private Color[] shadowColors;
	private Insets borderInsets;
	private final RenderingConfig renderingConfig = new RenderingConfig();

	public RichTitleBorder()
	{
		initShadow(shadowSize);
	}

	public RichTitleBorder(String aTitle)
	{
		title = aTitle;
		initShadow(shadowSize);
	}

	public RichTitleBorder(String aTitle, Font font)
	{
		title = aTitle;
		titleFont = font;
		initShadow(shadowSize);
	}

	public RichTitleBorder(Icon aIcon, String aTitle)
	{
		icon = aIcon;
		title = aTitle;
		initShadow(shadowSize);
	}

	public RichTitleBorder(ICSetting iTitle)
	{
		i18nTitle = iTitle;
		initShadow(shadowSize);
	}

	public RichTitleBorder(Icon aIcon, ICSetting iTitle)
	{
		icon = aIcon;
		i18nTitle = iTitle;
		initShadow(shadowSize);
	}

	public RichTitleBorder(Icon aIcon, String aTitle, int aShadowSize,
			int aInnerSpace)
	{
		icon = aIcon;
		title = aTitle;
		shadowSize = aShadowSize;
		if (shadowSize > 0)
			initShadow(shadowSize);
		innerSpace = aInnerSpace;
	}

	public RichTitleBorder(Icon aIcon, ICSetting iTitle, int aShadowSize,
			int aInnerSpace)
	{
		icon = aIcon;
		i18nTitle = iTitle;
		shadowSize = aShadowSize;
		if (shadowSize > 0)
			initShadow(shadowSize);
		innerSpace = aInnerSpace;
	}

	public void setIcon(Icon icon)
	{
		this.icon = icon;
	}

	public void setShadowSize(int shadowSize)
	{
		if (shadowSize < 0 || this.shadowSize == shadowSize)
			return;
		this.shadowSize = shadowSize;
		if (shadowSize > 0)
			initShadow(shadowSize);
	}

	private void initShadow(int shadowSize)
	{
		shadowColors = new Color[shadowSize];
		int opacity = shadowOpacity;
		int r = shadowColor.getRed();
		int g = shadowColor.getGreen();
		int b = shadowColor.getBlue();
		for (int i = 0; i < shadowSize; i++)
		{
			shadowColors[i] = new Color(r, g, b, opacity);
			opacity = opacity / 2;
		}
	}

	public void setInnerSpace(int innerSpace)
	{
		this.innerSpace = innerSpace;
	}

	@Override
	public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
	{
		ownerComponent = c;
		Graphics2D g2d = (Graphics2D) g;
		Composite saveComposite = g2d.getComposite();
		renderingConfig.setAllAAPainting(g2d);
		if (shadowSize > 0)
		{
			int rr = arc + 2;
			int gap = rr / 2 + 1;
			int x1 = x + w - shadowSize, y1 = y + h - shadowSize;
			int xx = x + arc / 2 + 4, yy = y + arc / 2 + 4;
			for (int i = 0; i < shadowSize; i++)
			{
				g2d.setColor(shadowColors[i]);
				g2d.drawLine(x1 + i, yy, x1 + i, y1 - gap + i);
				g2d.drawLine(xx, y1 + i, x1 - gap + i, y1 + i);
				g2d.drawArc(x1 - rr + i, y1 - rr + i, rr, rr, 0, -90);
			}
		}
		int titleHeight = getBorderInsets(c).top - innerSpace - 3;
		g2d.setComposite(alphaComposite.derive(0.3f));
		Shape roundRect = new RoundRectangle2D.Float(x + 1, y + 1,
				w - shadowSize - 3, h - shadowSize - 3, arc, arc);
		if (!UITools.isBlack())
		{
			// Shape saveClip = g2d.getClip();
			// g2d.setClip(roundRect);
			g2d.setPaint(RThemeColor.createVerGradientPaint(x + 2, y + 2,
					w - shadowSize - 4, titleHeight));
			g2d.fillRoundRect(x + 2, y + 2, w - shadowSize - 4, titleHeight, 2,
					2);
			// g2d.setClip(saveClip);
		}
		g2d.setComposite(saveComposite);
		g2d.setColor(loColor);
		g2d.drawLine(x + 2, y + borderInsets.top - innerSpace - 1,
				x + w - shadowSize - 3, y + borderInsets.top - innerSpace - 1);

		if (UITools.isLight())
		{
			//			g2d.setColor(loColor);
			//			g2d.drawRoundRect(x, y, w - shadowSize - 1, h - shadowSize - 1,
			//					arc + 3, arc + 3);
			g2d.setColor(hiColor);
		} else
			g2d.setColor(RThemeColor.colorSet.borderColor);
		Stroke saveStroke = g2d.getStroke();
		g2d.setStroke(GraphicsTools.getLargeStroke());
		g2d.draw(roundRect);
		//		g2d.drawRoundRect(x + 1, y + 1, w - shadowSize - 3, h - shadowSize - 3,
		//				arc, arc);
		g2d.setStroke(saveStroke);

		paintTitle(c, g2d, x, y, w, h, titleHeight,
				RThemeColor.colorSet.textColor, null);
		renderingConfig.resetAllAAPainting(g2d);
	}

	private void paintTitle(Component c, Graphics g, int x, int y, int w, int h,
			int titleHeight, Color textColor, Color shadowColor)
	{
		x += 4 + innerSpace;
		if (icon != null)
		{
			int yc = y + 2 + ((titleHeight - icon.getIconHeight()) / 2);
			icon.paintIcon(c, g, x, yc);
			x += icon.getIconWidth() + 4;
		}
		String title = getTitle();
		if (title != null)
		{
			g.setFont(getFont(c));
			FontMetrics fm = g.getFontMetrics();
			y += fm.getHeight();
			if (shadowColor != null)
			{
				g.setColor(shadowColor);
				g.drawString(title, x + 1, y + 1);
			}
			g.setColor(textColor);
			g.drawString(title, x, y);
		}
	}

	@Override
	public Insets getBorderInsets(Component c)
	{
		Font font = getFont(c);
		if (borderInsets == null || (font != null && !font.equals(titleFont)))
		{
			Graphics g = c.getGraphics();
			titleFont = font;
			if (g != null)
			{
				FontMetrics fm = g.getFontMetrics(titleFont);
				int frameWidth = 2 + innerSpace;
				int titleHeight = fm.getHeight();
				titleHeight += titleHeight / 4;
				if (icon != null)
					titleHeight = Math.max(titleHeight,
							icon.getIconHeight() + (icon.getIconHeight() / 4));
				borderInsets = new Insets(titleHeight + frameWidth, frameWidth,
						frameWidth + shadowSize, frameWidth + shadowSize);
			}
		}
		if (borderInsets != null)
			return borderInsets;
		return new Insets(0, 0, 0, 0);
	}

	@Override
	public Font getTitleFont()
	{
		if (titleFont == null)
			titleFont = FontTools.getSystemFont(13);
		if (i18nTitle != null && i18nTitle.isFontChange())
			return i18nTitle.getFont(titleFont);
		return titleFont;
	}

	@Override
	protected Component getOwnerComponent()
	{
		return ownerComponent;
	}
}
